 /* *************************** hello_drv.c *************************** */
 /*
 虚拟字符设备：简单实现对设备文件的读写操作
*/

#include <linux/kernel.h>


#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>

#include <linux/uaccess.h>
#include <linux/interrupt.h>


struct device_info
{
dev_t dev_num;//设备号
int dev_major;  //主次设备号
int dev_minor;
struct cdev cdev_test;//设备结构体信息
struct class *class;//类和对象
struct device *device;
char kernel_buf[1024];
};

struct device_info dev1;

struct tasklet_struct mytestirq;


void irq_function(unsigned long data){
	printk("This is irq_function and data is %ld\n",data);
	return;
}


/*static init  静态初始化*/
/* DECLARE_TASKLET(mytestirq,irq_function,1);*/



static struct file_operations dev_operation = {
       .owner = THIS_MODULE,

  };


 
/* 驱动入口函数 */
static int  hello_init(void) {
	int ret;
 
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);

	ret= alloc_chrdev_region(&dev1.dev_num,0,1,"alloc_name");//动态申请设备号，次设备从0开始，申请一个
	if(ret<0){

		printk("alloc_chrdev_region is error\n");
	}
	printk("alloc_chrdev_region is ok\n");

	dev1.dev_major = MAJOR(dev1.dev_num); 
	dev1.dev_major = MINOR(dev1.dev_num);  

	printk("major is %d\n",dev1.dev_major);
	printk("minot is %d\n",dev1.dev_major);

	dev1.cdev_test.owner = THIS_MODULE;
	cdev_init(&dev1.cdev_test,&dev_operation);
	cdev_add(&dev1.cdev_test,dev1.dev_num,1);

	dev1.class = class_create(THIS_MODULE, "test");
	dev1.device = device_create(dev1.class,NULL,dev1.dev_num,NULL,"my_first_dev");


	/*动态初始化*/
	tasklet_init(&mytestirq,irq_function,1);

	/*调度中断下文绑定的函数*/
	tasklet_schedule(&mytestirq);
	return 0;
	
}
 
/* 驱动出口函数 */
static void  hello_exit(void)	{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	/*使能状态*/
	tasklet_enable(&mytestirq);
	/*关闭调度*/
	tasklet_kill(&mytestirq);
	
	device_destroy(dev1.class, dev1.dev_num);
	class_destroy(dev1.class);
	cdev_del(&dev1.cdev_test);
	unregister_chrdev_region(dev1.dev_num, 1);
	
}
module_init(hello_init);	/*指定设备驱动入口函数*/
module_exit(hello_exit);	/*指定设备驱动出口函数*/
MODULE_LICENSE("GPL");
